package cc.gu.tank.scene;

import cc.gu.tank.Director;
import cc.gu.tank.enums.Direction;
import cc.gu.tank.enums.Group;
import cc.gu.tank.sprite.*;
import javafx.animation.AnimationTimer;
import javafx.event.EventHandler;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: GuSongLiao
 * @Date: 2025/9/29 9:33
 * @Description: 游戏中的场景
 */
public class GameScene {

    private static Canvas canvas = new Canvas(Director.WIDTH, Director.HEIGHT);
    private static GraphicsContext graphicsContext2D = canvas.getGraphicsContext2D();

    private KeyProcess keyProcess = new KeyProcess();
    private Refresh refresh = new Refresh();
    private boolean running = true;

    /**
     * 自己的坦克
     */
    private static Tank self = new Tank(Direction.UP, Director.WIDTH / 2, Director.HEIGHT / 2);

    static int ENEMY_COUNT = 10;
    static int TREE_COUNT = 10;
    static int CRATE_COUNT = 10;
    static int ROCK_COUNT = 15;

    static Stage stage;

    //
    public static Background background = new Background();
    //障碍物
    public static List<Sprite> obstacles = new ArrayList<>();
    public static List<Tank> tanks = new ArrayList<>();

    public void init(Stage stage) {
        //添加背景、角色、敌人、墙等
        initSprites();

        AnchorPane pane = new AnchorPane();
        pane.getChildren().add(canvas);
        stage.getScene().setRoot(pane);
        //绑定监听等
        //键盘按下监听
        stage.addEventHandler(KeyEvent.KEY_PRESSED, keyProcess);
        //键盘抬起监听
        stage.addEventHandler(KeyEvent.KEY_RELEASED, keyProcess);
        this.stage = stage;
        refresh.start();
    }

    public void initSprites() {
        //障碍物
        for (int i = 0; i < TREE_COUNT; i++) {
            obstacles.add(new Tree(i * Tree.WIDTH + 100, 100));
        }

        for (int i = 0; i < CRATE_COUNT; i++) {
            obstacles.add(new Crate(i * Crate.WIDTH + 100, 300));
        }

        for (int i = 0; i < ROCK_COUNT; i++) {
            obstacles.add(new Rock(i * Rock.WIDTH + 100, 500));
        }

        //坦克集合
        tanks.add(self);
        //左上角敌人
        for (int i = 0; i < ENEMY_COUNT; i++) {
            tanks.add(new Tank(Direction.DOWN, i * Tank.WIDTH + 10, 0, Group.ENEMY, true));
        }


    }

    public void paint() {
        //子弹集合
        List<Bullet> bullets = tanks.stream().flatMap(tank -> tank.bullets.stream()).collect(Collectors.toList());

        background.draw(graphicsContext2D);


        Iterator<Tank> tanksIterator = tanks.iterator();
        while (tanksIterator.hasNext()) {
            Tank tank = tanksIterator.next();
            if (tank.isAlive()) {
                tank.impact(tanks);
                tank.impact(bullets);
                tank.impact(obstacles);
                tank.draw(graphicsContext2D);
                Iterator<Bullet> bulletIterator = tank.bullets.iterator();
                while (bulletIterator.hasNext()) {
                    Bullet bullet = bulletIterator.next();
                    if (bullet.isAlive()) {
                        bullet.impact(tanks);
                        bullet.impact(obstacles);
                        bullet.draw(graphicsContext2D);
                        if (bullet.boom != null) {
                            if (bullet.boom.isAlive()) {
                                bullet.boom.draw(graphicsContext2D);
                            } else {
                                bullet.boom = null;
                            }

                        }
                    } else {
                        bulletIterator.remove();
                    }
                }
            } else {
                tanksIterator.remove();
            }
        }

        Iterator<Sprite> iterator = obstacles.iterator();
        while (iterator.hasNext()) {
            Sprite sprite = iterator.next();
            if (sprite.isAlive()) {
                sprite.draw(graphicsContext2D);
            } else {
                iterator.remove();
            }
        }

        if (!self.isAlive()) {
            //跳转游戏结束页面
            Director.getInstance().gameOver();
            new Thread(() -> {
                //刚结束还有声音3秒后清除,
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                clear();
            });

        }

    }


    private class Refresh extends AnimationTimer {

        @Override
        public void handle(long now) {
            if (running) {
                paint();
            }
        }
    }

    public void clear() {
        obstacles.clear();
        tanks.clear();
        background = null;
        stage.getScene().removeEventHandler(KeyEvent.KEY_PRESSED, keyProcess);
        stage.getScene().removeEventHandler(KeyEvent.KEY_RELEASED, keyProcess);

    }

    private class KeyProcess implements EventHandler<KeyEvent> {

        @Override
        public void handle(KeyEvent event) {
            KeyCode keyCode = event.getCode();


            if (event.getEventType() == KeyEvent.KEY_RELEASED) {
                if (keyCode.equals(KeyCode.SPACE)) {
                    pauseOrContinue();
                }

                if (self != null) self.released(keyCode);
            } else if (event.getEventType() == KeyEvent.KEY_PRESSED) {
                if (self != null) self.pressed(keyCode);
            }
        }
    }

    public void pauseOrContinue() {
        running = !running;
    }

}
